import json

from common.equipment.interface import create_equip
from common.player.reference import Player
from gui.signals import SIGNALS
from utils.settings import SAVE_DIR


class CustomJsonEncoder(json.JSONEncoder):
    def default(self, obj):
        if hasattr(obj, '__json__'):
            return obj.__json__()

        return super(CustomJsonEncoder, self).default(obj)


def game_save(player: Player):
    filepath = SAVE_DIR / f'{player.name}.json'
    data = {
        'name': player.name,
        'map_name': player.map_name,
        'pos': player.pos,
        'bag': player.bag,
        'quest': player.quest_book,
        'state': player.state,
        'slot': player.equip_slots
    }
    with open(filepath, 'w', encoding='utf-8') as f:
        json.dump(data, f, cls=CustomJsonEncoder, ensure_ascii=False, indent=4)

    SIGNALS.send_message.emit('存档完成')


def game_load(name: str):
    filepath = SAVE_DIR / f'{name}.json'
    if not filepath.exists():
        return None

    with open(filepath, 'r', encoding='utf-8') as f:
        data = json.load(f)

    player = Player(data['name'])
    player.map_name = data['map_name']
    player.pos.load(data['pos'])
    player.bag.load(data['bag'])
    player.quest_book.load(data['quest'])
    player.state.load(data['state'])

    for slot, meta in data['slot'].items():
        if meta is None:
            continue
        meta.pop('key')
        if 'attrs' in meta:
            meta.update(meta.pop('attrs'))

        e = create_equip(slot, meta, meta['quality'])
        player.equip_slots[slot] = e

    return player
